{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "02164.ipynb",
      "provenance": [],
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/yananma/5_programs_per_day/blob/master/02164.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "1rrBS9SYCduP",
        "colab_type": "text"
      },
      "source": [
        "## 5.9 含并行连接的网络 ( GoogLeNet )"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "NIktMIFTDGGN",
        "colab_type": "text"
      },
      "source": [
        "### 5.9.1 Inception 块"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "RroTTExnDNy_",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import torch \n",
        "from torch import nn, optim \n",
        "import torch.nn.functional as F \n",
        "import d2l \n",
        "import time \n",
        "device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n",
        "\n",
        "\n",
        "class Inception(nn.Module):\n",
        "    def __init__(self, in_c, c1, c2, c3, c4):\n",
        "        super(Inception, self).__init__()\n",
        "        self.p1_1 = nn.Conv2d(in_c, c1, kernel_size=1)\n",
        "        self.p2_1 = nn.Conv2d(in_c, c2[0], kernel_size=1)\n",
        "        self.p2_2 = nn.Conv2d(c2[0], c2[1], kernel_size=3, padding=1)\n",
        "        self.p3_1 = nn.Conv2d(in_c, c3[0], kernel_size=1)\n",
        "        self.p3_2 = nn.Conv2d(c3[0], c3[1], kernel_size=5, padding=2)\n",
        "        self.p4_1 = nn.MaxPool2d(kernel_size=3, stride=1, padding=1)\n",
        "        self.p4_2 = nn.Conv2d(in_c, c4, kernel_size=1)\n",
        "\n",
        "    def forward(self, x):\n",
        "        p1 = F.relu(self.p1_1(x))\n",
        "        p2 = F.relu(self.p2_2(F.relu(self.p2_1(x))))\n",
        "        p3 = F.relu(self.p3_2(F.relu(self.p3_1(x))))\n",
        "        p4 = F.relu(self.p4_2(self.p4_1(x)))\n",
        "        return torch.cat((p1, p2, p3, p4), dim=1)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "8wBOvTBaMllC",
        "colab_type": "text"
      },
      "source": [
        "### 5.9.2 GoogLeNet 模型"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "XSsXBUXGMw5o",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "b1 = nn.Sequential(nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3), \n",
        "          nn.ReLU(), \n",
        "          nn.MaxPool2d(kernel_size=3, stride=2, padding=1))"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "X6zgWYRrNFoG",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "b2 = nn.Sequential(nn.Conv2d(64, 64, kernel_size=1), \n",
        "          nn.Conv2d(64, 192, kernel_size=3, padding=1), \n",
        "          nn.MaxPool2d(kernel_size=3, stride=2, padding=1))"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "EEatk48FNZUQ",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "b3 = nn.Sequential(Inception(192, 64, (96, 128), (16, 32), 32), \n",
        "          Inception(256, 128, (128, 192), (32, 96), 64), \n",
        "          nn.MaxPool2d(kernel_size=3, stride=2, padding=1))"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "_95kPJ32Nxwf",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "b4 = nn.Sequential(Inception(480, 192, (96, 208), (16, 48), 64), \n",
        "          Inception(512, 160, (112, 224), (24, 64), 64), \n",
        "          Inception(512, 128, (128, 256), (24, 64), 64), \n",
        "          Inception(512, 112, (144, 288), (32, 64), 64), \n",
        "          Inception(528, 256, (160, 320), (32, 128), 128), \n",
        "          nn.MaxPool2d(kernel_size=3, stride=2, padding=1))"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Z_qg9FehOpp-",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "b5 = nn.Sequential(Inception(832, 256, (160, 320), (32, 128), 128), \n",
        "          Inception(832, 384, (192, 384), (48, 128), 128), \n",
        "          d2l.GlobalAvgPool2d())"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "I3_1MkpVPbFg",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 134
        },
        "outputId": "c73efd78-a086-43aa-82b4-788697a188e4"
      },
      "source": [
        "net = nn.Sequential(b1, b2, b3, b4, b5, d2l.FlattenLayer(), nn.Linear(1024, 10))\n",
        "X = torch.rand(1, 1, 96, 96)\n",
        "for blk in net.children():\n",
        "    X = blk(X)\n",
        "    print('output shape: ', X.shape)"
      ],
      "execution_count": 10,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "output shape:  torch.Size([1, 64, 24, 24])\n",
            "output shape:  torch.Size([1, 192, 12, 12])\n",
            "output shape:  torch.Size([1, 480, 6, 6])\n",
            "output shape:  torch.Size([1, 832, 3, 3])\n",
            "output shape:  torch.Size([1, 1024, 1, 1])\n",
            "output shape:  torch.Size([1, 1024])\n",
            "output shape:  torch.Size([1, 10])\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "2PGe03aTQC9Q",
        "colab_type": "text"
      },
      "source": [
        "### 5.9.3 获取数据和训练模型"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Yukbc4ciQKy3",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 118
        },
        "outputId": "5aa462e4-8661-41d4-b32e-92cb57b8228e"
      },
      "source": [
        "batch_size = 128 \n",
        "train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=96)\n",
        "\n",
        "lr, num_epochs = 0.001, 5 \n",
        "optimizer = torch.optim.Adam(net.parameters(), lr=lr)\n",
        "d2l.train_ch5(net, train_iter, test_iter, batch_size, optimizer, device, num_epochs)"
      ],
      "execution_count": 12,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "training on  cuda\n",
            "epoch 1, loss 1.0029, train acc 0.615, test acc 0.794, time 132.4 sec\n",
            "epoch 2, loss 0.4163, train acc 0.846, test acc 0.839, time 132.3 sec\n",
            "epoch 3, loss 0.3385, train acc 0.874, test acc 0.870, time 132.4 sec\n",
            "epoch 4, loss 0.3003, train acc 0.889, test acc 0.894, time 132.1 sec\n",
            "epoch 5, loss 0.2697, train acc 0.900, test acc 0.892, time 132.6 sec\n"
          ],
          "name": "stdout"
        }
      ]
    }
  ]
}